/**
 * 坐骑训练逻辑测试脚本
 * 测试坐骑等级经验数据表和训练逻辑
 */

const mysql = require('mysql2/promise');

// 数据库配置
const dbConfig = {
  host: '43.143.253.188',
  user: 'nextjs',
  password: 'yEAiRE2jcxTyRBy5',
  database: 'nextjs',
  charset: 'utf8mb4'
};

class MountTrainingLogicTester {
  constructor() {
    this.connection = null;
    this.testResults = [];
  }

  // 运行完整测试流程
  async runTest () {
    console.log('🐎 开始坐骑训练逻辑测试...\n');
    console.log('测试目标：数据库连接 → 等级经验数据验证 → 训练逻辑测试\n');

    try {
      // 1. 连接数据库
      await this.testDatabaseConnection();

      // 2. 验证等级经验数据表
      await this.testMountLevelExperienceData();

      // 3. 测试等级计算逻辑
      await this.testLevelCalculationLogic();

      // 4. 测试经验获取逻辑
      await this.testExperienceGainLogic();

      // 5. 测试训练限制逻辑
      await this.testTrainingLimitLogic();

      // 6. 断开数据库连接
      await this.testDisconnect();

      // 输出测试结果
      this.printTestResults();

    } catch (error) {
      console.error('❌ 测试过程中发生错误:', error.message);
      this.addTestResult('整体测试', false, error.message);
    }
  }

  // 1. 数据库连接测试
  async testDatabaseConnection () {
    console.log('🔌 步骤1: 数据库连接测试...');

    try {
      this.connection = await mysql.createConnection(dbConfig);
      console.log('✅ 数据库连接成功');
      this.addTestResult('数据库连接', true, '连接建立成功');
    } catch (error) {
      console.log('❌ 数据库连接失败:', error.message);
      this.addTestResult('数据库连接', false, error.message);
      throw error;
    }
  }

  // 2. 验证等级经验数据表
  async testMountLevelExperienceData () {
    console.log('\n📊 步骤2: 验证等级经验数据表...');

    try {
      // 检查表是否存在
      const [tables] = await this.connection.execute(
        "SHOW TABLES LIKE 'mount_level_experience'"
      );

      if (tables.length === 0) {
        throw new Error('mount_level_experience表不存在');
      }

      // 检查数据量
      const [countResult] = await this.connection.execute(
        "SELECT COUNT(*) as count FROM mount_level_experience"
      );
      const count = countResult[0].count;

      if (count === 0) {
        throw new Error('mount_level_experience表没有数据');
      }

      console.log(`✅ 等级经验数据表验证成功，共${count}条记录`);
      this.addTestResult('等级经验数据表验证', true, `共${count}条记录`);

      // 验证数据完整性
      await this.validateDataIntegrity();

    } catch (error) {
      console.log('❌ 等级经验数据表验证失败:', error.message);
      this.addTestResult('等级经验数据表验证', false, error.message);
    }
  }

  // 验证数据完整性
  async validateDataIntegrity () {
    console.log('🔍 验证数据完整性...');

    try {
      // 检查必需字段
      const [fields] = await this.connection.execute(
        "DESCRIBE mount_level_experience"
      );

      const requiredFields = ['level', 'experience', 'exp_to_next', 'exp_per_training', 'training_count'];
      const existingFields = fields.map(field => field.Field);

      const missingFields = requiredFields.filter(field => !existingFields.includes(field));

      if (missingFields.length > 0) {
        throw new Error(`缺少必需字段: ${missingFields.join(', ')}`);
      }

      // 检查数据范围
      const [minMax] = await this.connection.execute(
        "SELECT MIN(level) as min_level, MAX(level) as max_level, MIN(experience) as min_exp, MAX(experience) as max_exp FROM mount_level_experience"
      );

      const { min_level, max_level, min_exp, max_exp } = minMax[0];

      console.log(`📊 数据范围: 等级${min_level}-${max_level}, 经验${min_exp}-${max_exp}`);

      // 验证等级递增
      const [levelCheck] = await this.connection.execute(
        "SELECT level FROM mount_level_experience ORDER BY level"
      );

      let isValid = true;
      for (let i = 1; i < levelCheck.length; i++) {
        if (levelCheck[i].level !== levelCheck[i - 1].level + 1) {
          isValid = false;
          break;
        }
      }

      if (!isValid) {
        throw new Error('等级数据不连续');
      }

      console.log('✅ 数据完整性验证通过');
      this.addTestResult('数据完整性验证', true, '所有验证通过');

    } catch (error) {
      console.log('❌ 数据完整性验证失败:', error.message);
      this.addTestResult('数据完整性验证', false, error.message);
    }
  }

  // 3. 测试等级计算逻辑
  async testLevelCalculationLogic () {
    console.log('\n🎯 步骤3: 测试等级计算逻辑...');

    try {
      // 测试不同经验值对应的等级
      const testCases = [
        { experience: 0, expectedLevel: 1 },
        { experience: 1000, expectedLevel: 1 },
        { experience: 10000, expectedLevel: 2 },
        { experience: 50000, expectedLevel: 3 },
        { experience: 100000, expectedLevel: 4 }
      ];

      let successCount = 0;

      for (const testCase of testCases) {
        const [result] = await this.connection.execute(
          "SELECT level FROM mount_level_experience WHERE experience <= ? ORDER BY experience DESC LIMIT 1",
          [testCase.experience]
        );

        const actualLevel = result.length > 0 ? result[0].level : 1;
        const isCorrect = actualLevel === testCase.expectedLevel;

        if (isCorrect) {
          console.log(`✅ 经验${testCase.experience} -> 等级${actualLevel} (正确)`);
          successCount++;
        } else {
          console.log(`❌ 经验${testCase.experience} -> 等级${actualLevel} (期望${testCase.expectedLevel})`);
        }
      }

      if (successCount === testCases.length) {
        console.log('✅ 等级计算逻辑测试通过');
        this.addTestResult('等级计算逻辑', true, `所有${testCases.length}个测试用例通过`);
      } else {
        console.log(`⚠️ 等级计算逻辑测试部分通过: ${successCount}/${testCases.length}`);
        this.addTestResult('等级计算逻辑', false, `${successCount}/${testCases.length}个测试用例通过`);
      }

    } catch (error) {
      console.log('❌ 等级计算逻辑测试失败:', error.message);
      this.addTestResult('等级计算逻辑', false, error.message);
    }
  }

  // 4. 测试经验获取逻辑
  async testExperienceGainLogic () {
    console.log('\n💎 步骤4: 测试经验获取逻辑...');

    try {
      // 测试不同等级的训练经验获取
      const [levels] = await this.connection.execute(
        "SELECT level, exp_per_training FROM mount_level_experience ORDER BY level LIMIT 5"
      );

      let successCount = 0;

      for (const level of levels) {
        const { level: mountLevel, exp_per_training } = level;

        // 验证经验值合理性
        const isValid = exp_per_training > 0 && exp_per_training < 100000;

        if (isValid) {
          console.log(`✅ 等级${mountLevel}训练获得经验: ${exp_per_training}`);
          successCount++;
        } else {
          console.log(`❌ 等级${mountLevel}训练经验异常: ${exp_per_training}`);
        }
      }

      if (successCount === levels.length) {
        console.log('✅ 经验获取逻辑测试通过');
        this.addTestResult('经验获取逻辑', true, `所有${levels.length}个等级测试通过`);
      } else {
        console.log(`⚠️ 经验获取逻辑测试部分通过: ${successCount}/${levels.length}`);
        this.addTestResult('经验获取逻辑', false, `${successCount}/${levels.length}个等级测试通过`);
      }

    } catch (error) {
      console.log('❌ 经验获取逻辑测试失败:', error.message);
      this.addTestResult('经验获取逻辑', false, error.message);
    }
  }

  // 5. 测试训练限制逻辑
  async testTrainingLimitLogic () {
    console.log('\n🚫 步骤5: 测试训练限制逻辑...');

    try {
      // 检查训练次数限制数据
      const [trainingLimits] = await this.connection.execute(
        "SELECT level, training_count FROM mount_level_experience ORDER BY level LIMIT 5"
      );

      let successCount = 0;

      for (const limit of trainingLimits) {
        const { level, training_count } = limit;

        // 验证训练次数限制合理性
        const isValid = training_count > 0 && training_count <= 20;

        if (isValid) {
          console.log(`✅ 等级${level}每日训练限制: ${training_count}次`);
          successCount++;
        } else {
          console.log(`❌ 等级${level}训练限制异常: ${training_count}次`);
        }
      }

      if (successCount === trainingLimits.length) {
        console.log('✅ 训练限制逻辑测试通过');
        this.addTestResult('训练限制逻辑', true, `所有${trainingLimits.length}个等级测试通过`);
      } else {
        console.log(`⚠️ 训练限制逻辑测试部分通过: ${successCount}/${trainingLimits.length}`);
        this.addTestResult('训练限制逻辑', false, `${successCount}/${trainingLimits.length}个等级测试通过`);
      }

    } catch (error) {
      console.log('❌ 训练限制逻辑测试失败:', error.message);
      this.addTestResult('训练限制逻辑', false, error.message);
    }
  }

  // 6. 断开数据库连接
  async testDisconnect () {
    console.log('\n🔌 步骤6: 断开数据库连接...');
    if (this.connection) {
      await this.connection.end();
    }
    this.addTestResult('断开连接', true, '连接已断开');
  }

  // 添加测试结果
  addTestResult (testName, success, message) {
    this.testResults.push({
      test: testName,
      success: success,
      message: message,
      timestamp: new Date().toISOString()
    });
  }

  // 打印测试结果
  printTestResults () {
    console.log('\n📊 测试结果汇总:');
    console.log('='.repeat(50));

    let successCount = 0;
    let totalCount = this.testResults.length;

    this.testResults.forEach((result, index) => {
      const status = result.success ? '✅' : '❌';
      console.log(`${index + 1}. ${status} ${result.test}: ${result.message}`);
      if (result.success) successCount++;
    });

    console.log('='.repeat(50));
    console.log(`总计: ${successCount}/${totalCount} 项测试通过`);

    if (successCount === totalCount) {
      console.log('🎉 所有测试通过！坐骑训练系统逻辑正确！');
    } else {
      console.log('⚠️  部分测试失败，请检查日志');
    }

    // 输出系统状态
    console.log('\n🐎 坐骑训练系统状态:');
    console.log('='.repeat(50));
    console.log('✅ 等级经验数据表已创建');
    console.log('✅ 坐骑训练服务已实现');
    console.log('✅ 等级计算逻辑已更新');
    console.log('✅ 经验获取逻辑已更新');
    console.log('⚠️  WebSocket连接需要服务器支持');
    console.log('📝 建议：启动NestJS服务器进行完整测试');
  }
}

// 运行测试
async function main () {
  const tester = new MountTrainingLogicTester();
  await tester.runTest();
}

// 如果直接运行此脚本
if (require.main === module) {
  main().catch((error) => {
    console.error('💥 测试脚本执行失败:', error.message);
    process.exit(1);
  });
}

module.exports = MountTrainingLogicTester;
